package com.szsh.aiot.framework.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.jackson.JacksonProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;

/**
 * jackson支持Gson配置
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
@EnableConfigurationProperties(JacksonProperties.class)
public class JacksonCustomizer implements Jackson2ObjectMapperBuilderCustomizer {

    private Gson gson;

    @Autowired
    public void setGson(Gson gson) {
        this.gson = gson;
    }

    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
        // 反序列化
        jacksonObjectMapperBuilder.deserializerByType(JsonObject.class, new JsonDeserializer<JsonObject>() {
            @Override
            public JsonObject deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
                return gson.fromJson(p.getCodec().readTree(p).toString(), JsonObject.class);
            }
        });
        jacksonObjectMapperBuilder.deserializerByType(JsonArray.class, new JsonDeserializer<JsonArray>() {
            @Override
            public JsonArray deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
                return gson.fromJson(p.getCodec().readTree(p).toString(), JsonArray.class);
            }
        });

        // 序列化
        jacksonObjectMapperBuilder.serializerByType(JsonElement.class, new JsonSerializer<JsonElement>() {

            @Override
            public void serialize(JsonElement value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                if (null == value) {
                    gen.writeNull();
                } else {
                    gen.writeRawValue(gson.toJson(value));
                }
            }
        });
    }

}
